---
title: Title-case a string
summary: Converts a string to human-readable title case using curated word-classification rules while preserving original delimiters.
status: draft
owner: SAIF Documentation Generation
last_reviewed: 2026-08-21
library: SAIF.Business.Utilities
reference_type: embedded
operation_id: OP-UTIL-001
trigger: Call to TitleCase.ToTitleCase or the .ToTitleCase() extension method
---

# Title-case a string

This operation converts raw, often all-caps, stored text (names, addresses, statuses) into human-readable mixed case, using static word lists to classify exceptions, while preserving the original punctuation and whitespace of the input.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-UTIL-001 |
| **Trigger** | Caller invokes `TitleCase.ToTitleCase(inString)` directly, or the `.ToTitleCase()` extension method on a `String`. |
| **Inputs** | A `String`, possibly `Nothing`, empty, or whitespace-only. |
| **Outputs** | The title-cased `String`, with original delimiter characters preserved. |
| **Primary components** | `TitleCase.ToTitleCase`, `TitleCase.TitleCaseSingleWord`, `TitleCase.ReassembleString`, `TitleCase.ApplyExactSuffixList` |
| **Entry point** | `SAIF.Business.Utilities\TitleCase.vb` |

## Steps

1. Return the input unchanged if it is `Nothing` or blank after trimming. ([BR-UTIL-001](../business-rules.md#br-util-001-blank-or-null-input-passthrough))
2. Split the trimmed input into word tokens on any character that is not a letter or digit, using `Regex.Split(inString.Trim, "[^\d\w]")` (BCL `System.Text.RegularExpressions`).
3. If no non-empty tokens resulted (i.e., the whole string was delimiters), return the original string unchanged. ([BR-UTIL-001](../business-rules.md#br-util-001-blank-or-null-input-passthrough))
4. Otherwise, title-case each token individually via `TitleCaseSingleWord`:
   - If the token already contains both an upper-case and a lower-case letter, leave it untouched. ([BR-UTIL-002](../business-rules.md#br-util-002-mixed-case-tokens-are-left-untouched))
   - If the token (case-insensitively) matches a known all-caps abbreviation (`SAIF`, `LLC`, `LLP`, `MD`, `JD`, `NE`, `NW`, `OR`, `CA`, `WA`, etc.), render it fully upper case. ([BR-UTIL-003](../business-rules.md#br-util-003-known-all-caps-abbreviations-stay-upper-case))
   - If the token (case-insensitively) matches a known connector word (`is`, `in`, `the`, `an`, `of`, `on`, `and`, `de`), render it fully lower case. ([BR-UTIL-004](../business-rules.md#br-util-004-known-connector-words-stay-lower-case))
   - If the token (case-insensitively) matches a curated mixed-case exception (`PhD`, `LaCombe`), replace it with the canonical mixed-case spelling. ([BR-UTIL-005](../business-rules.md#br-util-005-known-mixed-case-exception-words-are-normalized))
   - If the token is a numeric prefix followed by an ordinal suffix (`st`, `nd`, `rd`, `th`), keep the number unchanged and lower-case the suffix. ([BR-UTIL-006](../business-rules.md#br-util-006-ordinal-number-suffixes-are-lower-cased))
   - Otherwise, proper-case the token; if the proper-cased result starts with a recognized name prefix (`Mc`, `O'`), separately proper-case the remainder after the prefix to add an inner capital. ([BR-UTIL-007](../business-rules.md#br-util-007-mc-o'-style-prefixes-get-a-second-inner-capital))
5. Reassemble the title-cased tokens back into a single string using `ReassembleString`, re-inserting the exact original delimiter characters (punctuation/whitespace) between tokens.
6. Re-apply an exact-suffix pass (`ApplyExactSuffixList`) per space-delimited word, to correctly case trailing possessive `'s` suffixes that the regex tokenizer would otherwise split apart. ([BR-UTIL-008](../business-rules.md#br-util-008-possessive-'s-suffix-is-preserved-in-original-case))
7. Force the first character of the final output to upper case (regardless of what the word-casing rules produced), then return the result. ([BR-UTIL-009](../business-rules.md#br-util-009-first-character-of-output-is-always-forced-to-upper-case))

No step in this operation delegates into another project/library in this repository or into a SAIF BOF Framework operation — the operation is entirely self-contained BCL-only logic (string/regex manipulation).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Trigger: ToTitleCase call]) --> Guard{Null/blank input?}
	Guard -->|Yes| ReturnUnchanged([Return input unchanged])
	Guard -->|No| Split[Regex.Split into tokens]
	Split --> NoTokens{No non-empty tokens?}
	NoTokens -->|Yes| ReturnUnchanged
	NoTokens -->|No| Classify[TitleCaseSingleWord per token]
	Classify --> Reassemble[ReassembleString with original delimiters]
	Reassemble --> Suffix[ApplyExactSuffixList for possessive suffix]
	Suffix --> ForceCap[Force first character upper case]
	ForceCap --> End([Return title-cased string])
```

## Failure and edge-case behavior
- Null, empty, or whitespace-only input: returned unchanged, no exception raised.
- Input consisting entirely of delimiter characters (no letters/digits): returned unchanged.
- Consumers rely on this operation to have no side effects and no thrown exceptions under normal string input.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- SAIF.Business.Utilities\TitleCase.vb
- .saifdocgen/state/runs/20260821-113120-claims-bof-web-legal/analysis/TSK007-analysis.md
